#include "sensorInterface.h"
#include "serial_linux.h"
#include "debug.h"
#include <pthread.h>

static sensorDevice_s g_sensor_device = {
    "",
    0,
    RELEASED,
    -1,
    NULL
};


int startThread(void *thread, void *parm)
{
    d_info("E\n");
    int ret = 0;

    pthread_t thread_id;
    pthread_attr_t pattr;
    pthread_attr_init(&pattr);
    pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED);
    ret = pthread_create(&thread_id, &pattr, thread,(void*)parm);
    pthread_attr_destroy(&pattr);

    d_info("X\n");
    return ret;
}

void* grab_thread(void *parm)
{
    d_info("E\n");
    int ret = 0;
    char buf[DATALEN_MAX];


    g_sensor_device.grabing = 1;

    while(g_sensor_device.grabing){
        //ret = serial_read_once(g_sensor_device.fd, buf, 10, 1000);
        ret = serial_read(g_sensor_device.fd, buf, 1, 1000);
        if(ret > 0){
            if(g_sensor_device.onreceivecb){
                g_sensor_device.onreceivecb(buf, ret);
            }
        }else if(ret < 0){
            d_error("grab data error\n");
            break;
        }
    }

    d_info("X\n");
    return NULL;
}

int stop(int fd)
{
    char cmd[] = {0x20, 0x33};
    const int reslen = 2;
    char res[reslen];
    int ret = 0;

    ret = serial_write(fd, cmd,  sizeof(cmd));
    if(ret == sizeof(cmd)){
        ret = serial_read(fd, res, reslen, 1000);
        if(ret == reslen && res[0] == 0x20 && res[1] == 0x33){
            ret = 0;
        }
    }
    usleep(500000);
    tcflush(fd, TCIOFLUSH);

    return 0;
}

int start(int fd)
{
    char cmd[] = {0x20, 0x32};
    const int reslen = 2;
    char res[reslen];
    int ret = 0;

    ret = serial_write(fd, cmd,  sizeof(cmd));
    if(ret == sizeof(cmd)){
        ret = serial_read(fd, res, reslen, 2000);
        if(ret == reslen && res[0] == 0x20 && res[1] == 0x32){
            ret = 0;
        }
    }

    return ret;
}

int sensor_init(char *path)
{
    int ret = 0;
    d_info("E\n");
    if(path == NULL){
        d_error("path is null \n");
        return -1;
    }

    if(g_sensor_device.status == RELEASED){
        strncpy(g_sensor_device.path, path, sizeof(g_sensor_device.path)-1);
        if((ret = serial_init(g_sensor_device.path)) >= 0){
            d_info("opend %s\n", g_sensor_device.path);
            stop(ret);
            g_sensor_device.fd = ret;
            g_sensor_device.grabing = 0;
            g_sensor_device.onreceivecb = NULL;
            g_sensor_device.status = INITED;
            ret = 0;
        }
    }else{
        d_error("called on status %d\n", g_sensor_device.status);
    }

    d_info("X\n");
    return ret;
}


//return 0 OK
int sensor_get_serialno(char *serialno)
{
    int ret = 0;
    char cmd[] = {0x20, 0x31};
    int reslen = 4;

    if(serialno == NULL){
        d_error("serialno is null \n");
        return -1;
    }

    if(g_sensor_device.status == INITED){
        ret = serial_write(g_sensor_device.fd, cmd,  sizeof(cmd));
        if(ret == sizeof(cmd)){
            ret = serial_read(g_sensor_device.fd, serialno, reslen, 1000);
            if(ret == reslen){
                ret = 0;
            }
        }
    }else{
        d_error("called on status %d\n", g_sensor_device.status);
        ret = -1;
    }

    return ret;
}

int sensor_start()
{
    int ret = 0;


    if(g_sensor_device.status == INITED){
        if(!start(g_sensor_device.fd)){
            ret = startThread(grab_thread, NULL);
            if(ret == 0){
                g_sensor_device.status = STARTED;
            }
        }
    }else if(g_sensor_device.status == STARTED){
        d_error("called on started\n");
        ret = 0;
    }else{
        d_error("called on released\n");
        ret = -1;
    }

    return ret;

}

int sensor_stop()
{
    int ret = 0;

    if(g_sensor_device.status == STARTED){
        g_sensor_device.grabing = 0;
        if(!stop(g_sensor_device.fd)){
            g_sensor_device.status = INITED;
        }
    }else if(g_sensor_device.status == INITED){
        d_error("called on started\n");
        ret = 0;
    }else{
        d_error("called on released\n");
        ret = -1;
    }

    return ret;

}
int sensor_set_zoomlevel()//0h-6h
{

}
int sensor_set_baseline_pos()//0h-3h
{

}
int sensor_set_samplerate()//0h-200hz;1h-250hz;2h-400hz;3h-500hz
{

}
int sensor_release()
{
    int ret = 0;
    if(g_sensor_device.status == STARTED){
        sensor_stop();
    }
    if(g_sensor_device.status == INITED){
        ret = serial_close(g_sensor_device.fd);
        g_sensor_device.fd = -1;
        g_sensor_device.status = RELEASED;
    }

    return ret;
}

int sensor_set_datacallback(data_callback onreceive)
{
    g_sensor_device.onreceivecb = onreceive;
}

